package org.jeecg.common.modules.order.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.tuple.MutableTriple;
import org.jeecg.common.modules.doctor.entity.DoctorRegisterRecord;
import org.jeecg.common.modules.order.entity.PayOrder;
import org.jeecg.common.modules.order.mapper.PayOrderMapper;
import org.jeecg.common.modules.order.service.IPayOrderService;
import org.jeecg.common.modules.wx.entity.WxUserinfo;
import org.jeecg.common.modules.wx.service.IWxUserinfoService;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.UidUtils;
import org.jeecg.common.util.enums.OrderTypeEnum;
import org.jeecg.common.util.enums.PayOrderStatusEnum;
import org.jeecg.common.util.enums.PayOrderTypeEnum;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;

/**
 * @Description: pay_order
 * @Author: jeecg-boot
 * @Date:   2020-08-26
 * @Version: V1.0
 */
@Service
public class PayOrderServiceImpl extends ServiceImpl<PayOrderMapper, PayOrder> implements IPayOrderService {

    @Resource
    private IWxUserinfoService wxUserinfoService;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public MutableTriple<Boolean, String,PayOrder> initRefund(PayOrder payOrder) {
        if (Objects.isNull(payOrder)){
            return MutableTriple.of(false,"未获取到支付信息", null);
        }
        if (hasPaying(payOrder.getId())){
            return MutableTriple.of(false,"该订单已在退款中",null);
        }
        PayOrder refundOrder = new PayOrder();
        BeanUtils.copyProperties(payOrder,refundOrder);
        refundOrder.setId(null);
        refundOrder.setOrderCode(IdUtil.getSnowflake(1,1).nextIdStr());
        refundOrder.setThirdOrderCode(null);
        refundOrder.setEndPayTime(null);
        refundOrder.setStartPayTime(null);
        refundOrder.setStatus(PayOrderStatusEnum.WAIT_PAING.getCode());
        refundOrder.setCreateTime(new Date());
        refundOrder.setRelationId(payOrder.getId());
        refundOrder.setOrderType(PayOrderTypeEnum.REFUND.getCode());
        save(refundOrder);
        payOrder.setRelationId(refundOrder.getId());
        payOrder.setStatus(PayOrderStatusEnum.REFUND_ING.getCode());
        updateById(payOrder);
        return MutableTriple.of(true,null,refundOrder);
    }

    @Override
    public PayOrder initPayOrder(String doctorId,String relationId, String wxUserinfoId, Long amount, OrderTypeEnum orderType) {
        Date now = new Date();
        PayOrder payOrder = new PayOrder();
        payOrder.setOrderCode(IdUtil.getSnowflake(1,1).nextIdStr());
        payOrder.setDoctorId(doctorId);
        payOrder.setWxUserinfoId(wxUserinfoId);
        payOrder.setAmount(amount);
        payOrder.setStartPayTime(now);
        payOrder.setStatus(PayOrderStatusEnum.WAIT_PAING.getCode());
        payOrder.setShopType(orderType.getCode());
        payOrder.setCreateTime(now);
        payOrder.setOrderType(PayOrderTypeEnum.PAY.getCode());
        payOrder.setRelationId(relationId);
        save(payOrder);
        return payOrder;
    }
    @Override
    public PayOrder initPayOrderSP(String doctorId, String relationId, Long amount, OrderTypeEnum orderType, String openid, Integer shopType, String medicalId) {
        Date now = new Date();
        PayOrder payOrder = new PayOrder();
//        payOrder.setOrderCode(IdUtil.getSnowflake(1,1).nextIdStr());
        payOrder.setOrderCode(UidUtils.getUid32());
        payOrder.setDoctorId(doctorId);
        payOrder.setAmount(amount);
        payOrder.setStartPayTime(now);
        payOrder.setStatus(PayOrderStatusEnum.WAIT_PAING.getCode());
        payOrder.setShopType(shopType);
        payOrder.setCreateTime(now);
        payOrder.setWxUserinfoId("1");
        payOrder.setOrderType(PayOrderTypeEnum.PAY.getCode());
        payOrder.setRelationId(relationId);
        payOrder.setOpenid(openid);
        payOrder.setMedicalId(medicalId);
        save(payOrder);
        return payOrder;
    }
    @Override
    public PayOrder getByOrderCode(String orderCode) {
        LambdaQueryWrapper<PayOrder> query = Wrappers.lambdaQuery();
        query.eq(PayOrder::getOrderCode,orderCode);
        return getOne(query);
    }

    private boolean hasPaying(String id){
        LambdaQueryWrapper<PayOrder> query = Wrappers.lambdaQuery();
        query.eq(PayOrder::getRelationId,id);
        query.in(PayOrder::getStatus, Lists.newArrayList(PayOrderStatusEnum.WAIT_PAING.getCode(),PayOrderStatusEnum.REFUND_ING.getCode(),PayOrderStatusEnum.REFUND.getCode()));
        query.eq(PayOrder::getOrderType,PayOrderTypeEnum.REFUND.getCode());
        return count(query) > 0;
    }
}
